package td.pt;

import java.util.ArrayList;

import td.client.ClientState;
import td.client.place.NameTokens;
import td.client.presenter.EditPresenter;
import td.client.presenter.LoginJoinPresenter;
import td.client.presenter.RootPresenter;
import td.client.presenter.handlers.RootUiHandlers;
import td.client.ui.Button;
import td.domain.Category;
import td.domain.DemoStore;
import td.domain.Thought;
import td.pt.event.EditEvent;
import td.pt.event.EditEvent.EditHandler;
import td.pt.event.ThoughtListingEvent;
import td.pt.event.UseCategoryNavigationEvent;
import td.pt.event.UseReferenceNavigationEvent;
import td.pt.event.UseReferenceNavigationEvent.ReferenceNavigationType;
import td.pt.event.UseTagNavigationEvent;
import td.pt.widget.CategoryTreePopupPresenter.CategoryNavigationType;
import td.pt.widget.NewTopicPopupPresenter;
import td.pt.widget.ReferenceListingPopupPresenter;
import td.pt.widget.TagListingPopupPresenter;
import td.pt.widget.TagTreePopupPresenter.TagNavigationType;

import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.user.client.Window;
import com.google.inject.Inject;
import com.google.web.bindery.event.shared.EventBus;
import com.gwtplatform.mvp.client.Presenter;
import com.gwtplatform.mvp.client.View;
import com.gwtplatform.mvp.client.annotations.ProxyStandard;
import com.gwtplatform.mvp.client.proxy.Proxy;
import com.gwtplatform.mvp.client.proxy.RevealContentEvent;

public class RightNavigationPresenter
		extends
		Presenter<RightNavigationPresenter.MyView, RightNavigationPresenter.MyProxy> {

	public interface MyView extends View {

		public Button getCreateThought();

		public Button getCategorize();

		public Button getTag();

		public Button getAddToActiveReferences();

		Button getAddAReference();

		public Button getPublish();
	}

	@ProxyStandard
	public interface MyProxy extends Proxy<RightNavigationPresenter> {
	}

	@Inject
	RootUiHandlers.MyView rootView;

	@Inject
	LoginJoinPresenter loginJoinPresenter;

	@Inject
	EditPresenter editPresenter;

	@Inject
	ClientState state;

	// FIXME: figure out the right way to get this presenter to be a part of
	// initial injection of everything
	@Inject
	TagListingPopupPresenter tagListingPopupPresenter;

	@Inject
	NewTopicPopupPresenter newTopicPopupPresenter;

	@Inject
	ReferenceListingPopupPresenter referenceListingPopupPresenter;

	EditHandler editHandler = new EditHandler() {

		@Override
		public void onEdit(EditEvent event) {
			getView().getCategorize().setVisible(true);
			getView().getPublish().setVisible(true);
		}
	};

	@Inject
	public RightNavigationPresenter(final EventBus eventBus, final MyView view,
			final MyProxy proxy) {
		super(eventBus, view, proxy);
	}

	@Override
	protected void revealInParent() {
		RevealContentEvent.fire(this, RootPresenter.SLOT_rightNavigation, this);
	}

	public void determineReferenceStatus(Thought thought) {
		if (state.getThinker() == null) {
			getView().getAddToActiveReferences().setVisible(false);
			getView().getTag().setVisible(false);
			getView().getAddAReference().setVisible(false);
		} else {
			if (!state.getThinker().getId()
					.equals(thought.getThinker().getId())) {
				getView().getTag().setVisible(true);
			} else {
				getView().getTag().setVisible(false);
			}
			getView().getAddToActiveReferences().setVisible(true);
			if (state.getThinker().getActiveReferences() != null
					&& state.getThinker().getActiveReferences()
							.contains(thought)) {
				getView()
						.getAddToActiveReferences()
						.setHTML(
								"<b>Thought in References</b><br/>Already in References to use");
				getView().getAddToActiveReferences().setEnabled(false);
			} else {
				getView()
						.getAddToActiveReferences()
						.setHTML(
								"<b>Save Thought to References</b><br/>Add to list of References to use");
				getView().getAddToActiveReferences().setEnabled(true);
			}
		}
	}

	@Override
	protected void onBind() {
		super.onBind();
		registerHandler(getEventBus().addHandler(EditEvent.TYPE, editHandler));
		getView().getAddToActiveReferences().addClickHandler(
				new ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						Thought thought = state.getCurrentThought();
						if (state.getThinker().getActiveReferences() == null) {
							state.getThinker().setActiveReferences(
									new ArrayList<Thought>());
						}
						state.getThinker().getActiveReferences()
								.add(state.getCurrentThought());
						determineReferenceStatus(thought);
					}
				});
		getView().getAddAReference().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				if (state.getThinker().getActiveReferences() == null) {
					state.getThinker().setActiveReferences(
							new ArrayList<Thought>());
				}
				UseReferenceNavigationEvent searchReferencesEvent = new UseReferenceNavigationEvent(
						ReferenceNavigationType.ADD_REFERENCE_TO_THOUGHT, state
								.getThinker().getDraft(),
						RightNavigationPresenter.this);
				getEventBus().fireEvent(searchReferencesEvent);
			}
		});
		getView().getCategorize().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				UseCategoryNavigationEvent searchCategoriesEvent = new UseCategoryNavigationEvent(
						CategoryNavigationType.ADD_THOUGHT_TO_CATEGORY,
						RightNavigationPresenter.this);
				getEventBus().fireEvent(searchCategoriesEvent);
			}
		});
		getView().getCreateThought().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				EditEvent editEvent = new EditEvent();
				getEventBus().fireEvent(editEvent);
				getView().getAddAReference().setVisible(true);

				if (state.getThinker().getActiveReferences() == null
						|| state.getThinker().getActiveReferences().size() < 1) {
					getView()
							.getAddAReference()
							.setHTML(
									"<b>No active References</b><br />Please save References first");
				} else {
					getView()
							.getAddAReference()
							.setHTML(
									"<b>Add a Reference</b><br />Add a Reference to another Thought");
				}

				getView().getCategorize().setVisible(true);
				getView().getPublish().setVisible(true);

				getView().getAddToActiveReferences().setVisible(false);
				getView().getTag().setVisible(false);
				getView().getCreateThought().setVisible(false);

			}
		});
		getView().getTag().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				UseTagNavigationEvent searchTagsEvent = new UseTagNavigationEvent(
						TagNavigationType.TAG_THOUGHT,
						RightNavigationPresenter.this);
				getEventBus().fireEvent(searchTagsEvent);
			}
		});

		getView().getPublish().addClickHandler(new ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				String title = editPresenter.getView().getTitle().getText();
				String synopsis = editPresenter.getView().getSynopsis()
						.getText();
				String text = editPresenter.getView().getThoughtBody()
						.getText();
				Thought draft = state.getThinker().getDraft();
				draft.setTitle(title);
				draft.setSynopsis(synopsis);
				draft.setText(text);
				if (draft != null & title != null && title.length() > 0
						& text != null && text.length() > 0
						& draft.getTopic() != null) {
					DemoStore.db().addThought(draft, state.getThinker(),
							draft.getTopic(), 0);
					state.getThinker().setDraft(null);
				} else {
					Window.alert("Thought must have Title, Category and Text set before being published");
					return;
				}

				if (draft != null
						& state.getThinker().getDraftReferences() != null) {
					for (Thought thought : state.getThinker()
							.getDraftReferences()) {
						DemoStore.db().addThoughtReference(draft, thought);
					}
				}

				ThoughtListingEvent<Category> newCategoryListingEvent = new ThoughtListingEvent<Category>(
						"Most Read Thoughts across all Categories", DemoStore
								.db().rootCategory);
				getEventBus().fireEvent(newCategoryListingEvent);
				getView().getCategorize().setVisible(false);
				getView().getPublish().setVisible(false);
				getView().getAddAReference().setVisible(false);

				getView().getCreateThought().setVisible(true);
			}
		});
	}

	public void onLogout() {
		getView().getCategorize().setVisible(false);
		getView().getCreateThought().setVisible(false);
		getView().getPublish().setVisible(false);
		getView().getAddToActiveReferences().setVisible(false);
		getView().getAddAReference().setVisible(false);
		getView().getTag().setVisible(false);
	}

	public void onLogin() {
		getView().getCreateThought().setVisible(true);
		if (state.getCurrentPlace().equals(NameTokens.detail)) {
			getView().getAddToActiveReferences().setVisible(true);
		}
	}

	@Override
	protected void onReset() {
		super.onReset();
	}
}
